﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Configuration;
using System.Windows.Forms.DataVisualization.Charting;
using System.ComponentModel.Design;
using System.Resources;
using System.Collections.Specialized;

namespace robotGUI
{
    public partial class graphControl : UserControl
    {
        //[Browsable(true)]
        //public override string Text { get { return groupBoxTitle.Text; } set { groupBoxTitle.Text = value; } }

        double _maximum = 255;
        public double ScaleMaximum { get { return _maximum; } set { _maximum = value; if (!_auto) graph.ChartAreas[0].AxisY.Maximum = value; } }
        double _minimum = -255;
        public double ScaleMinimum { get { return _minimum; } set { _minimum = value; if (!_auto) graph.ChartAreas[0].AxisY.Minimum = value; } }
        bool _auto = false;
        public bool ScaleAuto
        {
            set
            {
                _auto = value;
                if (value) { graph.ChartAreas[0].AxisY.Maximum = Double.NaN; graph.ChartAreas[0].AxisY.Minimum = Double.NaN; }
                else { graph.ChartAreas[0].AxisY.Maximum = _maximum; graph.ChartAreas[0].AxisY.Minimum = _minimum; }
            }
            get { return _auto; }
        }

        string _widthName = "sensorGraphWidth";
        public string WidthSetting { get { return _widthName; } set { _widthName = value; } }
        string _seriesName = "sensorGraphSeries";
        public string SeriesSetting { get { return _seriesName; } set { _seriesName = value; } }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public SeriesCollection Series { get { return graph.Series; } }
        int seriesCount;

        ItemCheckEventHandler itemCheckedEvent;
        public graphControl()
        {
            InitializeComponent();
            itemCheckedEvent = new ItemCheckEventHandler(listView1_ItemChecked);
        }

        private void graphControl_Load(object sender, EventArgs e)
        {
            numData.Value = graphWidth;
            if (graph.Series.Count != seriesCount)
            {
                populateSeriesList();
                checkedComboBox1.SetText();
                seriesCount = graph.Series.Count;
            }
        }

        private void populateSeriesList()
        {
            graph.ApplyPaletteColors();
            checkedComboBox1.Items.Clear();
            checkedComboBox1.ItemCheck -= itemCheckedEvent;
            for (int count = 0; count < Series.Count; count++)
            {                
                ListViewItem item = new ListViewItem(Series[count].Name);
                item.ForeColor = Series[count].Color;
                item.Checked = (graphSeries & (uint)Math.Pow(2, count)) > 0;
                if (Series[count].Label != null) item.ToolTipText = Series[count].Label;
                Series[count].Enabled = item.Checked;
                checkedComboBox1.Items.Add(item);
            }
            checkedComboBox1.ItemCheck += itemCheckedEvent;
        }

        int graphWidth { get { return (int)Properties.Settings.Default[_widthName]; } set { Properties.Settings.Default[_widthName] = value; } }
        uint graphSeries { get { return (uint)Properties.Settings.Default[_seriesName]; } 
            set { Properties.Settings.Default[_seriesName] = value; } }

        private void numRaw_ValueChanged(object sender, EventArgs e)
        {
            graphWidth = (int)numData.Value;
            graph.ChartAreas[0].AxisX.Maximum = (int)numData.Value;
            foreach (Series line in graph.Series)
                while (line.Points.Count > numData.Value) line.Points.RemoveAt(0);
        }

        private void listView1_ItemChecked(object sender, ItemCheckEventArgs e)
        {
            Series[e.Index].Enabled = (e.NewValue == CheckState.Checked);
            uint show = uint.MaxValue;
            for (int count = 0; count < checkedComboBox1.Items.Count; count++)
            {
                if (e.Index == count)
                {
                    if (e.NewValue != CheckState.Checked)
                        show -= (uint)Math.Pow(2, count);
                }
                else if (!checkedComboBox1.GetItemChecked(count))
                    show -= (uint)Math.Pow(2, count);
            }
            checkedComboBox1.SetText(e);
            graphSeries = show;
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            foreach (Series line in graph.Series)
                line.Points.Clear();
        }

        Bitmap bmp = (Bitmap)Properties.Resources.chart_line_error;
        private void graph_PostPaint(object sender, ChartPaintEventArgs e)
        {
            if (graph.Series.Count == 0 || graph.Series[0].Points.Count == 0)
            {
                System.Drawing.Graphics g = e.ChartGraphics.Graphics;
                System.Drawing.Font DrawFont = System.Drawing.SystemFonts.CaptionFont;
                System.Drawing.Brush DrawBrush = SystemBrushes.ControlDark;
                g.DrawString("No Data", DrawFont, DrawBrush, 32, 12);
                g.DrawImageUnscaled(bmp, 10, 10);
            }
        }

        public void Add(string series, double value)
        {
            if (graph.Series[series].Points.Count >= numData.Value)
                graph.Series[series].Points.RemoveAt(0);
            graph.Series[series].Points.Add(value);
            if (_auto) graph.ResetAutoValues();
        }
    }     
}
